package com.ddwl.goods.service;

import com.ddwl.common.exception.CommonException;
import com.ddwl.common.exception.ExceptionCode;
import com.ddwl.common.util.UUIDGenerator;
import com.ddwl.goods.dao.CategoryDao;
import com.ddwl.goods.mapper.BrandMapper;
import com.ddwl.goods.model.Brand;
import com.ddwl.goods.model.Category;
import com.ddwl.schema.bo.base.PageBo;
import com.ddwl.schema.bo.goods.BrandBo;
import com.ddwl.schema.bo.goods.BrandSearchBo;
import com.ddwl.schema.vo.base.PageVo;
import com.ddwl.schema.vo.goods.BrandVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Fu Zhaohui
 * @version 1.0.0
 * @date 2019/8/8 14:00
 */
@Service
public class BrandService {

    @Autowired
    private BrandMapper brandMapper;

    @Resource
    private CategoryDao categoryDao;

    @Transactional(rollbackFor = Throwable.class)
    public String create(BrandBo bo) {
        Brand entity = new Brand();
        BeanUtils.copyProperties(bo, entity);
        entity.setId(UUIDGenerator.getShortUUID());
        brandMapper.insert(entity);
        return entity.getId();
    }

    @Transactional(rollbackFor = Throwable.class)
    public void update(BrandBo bo) {
        Brand entity = new Brand();
        BeanUtils.copyProperties(bo, entity);
        brandMapper.update(entity);
    }

    public PageVo<BrandVo> page(PageBo<BrandSearchBo> pageBo) {
        PageVo<BrandVo> pageVo = new PageVo<>();
        BeanUtils.copyProperties(pageBo, pageVo);
        pageVo.setSize(pageBo.getPageSize());
        PageHelper.startPage(pageBo.getPage(), pageBo.getPageSize());
        Page<Brand> pageable = (Page<Brand>) brandMapper.findAll(pageBo.getParam());
        List<Brand> entities = pageable.getResult();
        Set<String> mchIds = new HashSet<>();
        Set<String> categoryIds = new HashSet<>();
        entities.forEach(entity -> {
            if (StringUtils.hasText(entity.getMchId())) {
                mchIds.add(entity.getMchId());
            }
            if (StringUtils.hasText(entity.getCategoryId())) {
                categoryIds.add(entity.getCategoryId());
            }
        });
        Map<String, String> mchMap = new HashMap<>();
        if (!mchIds.isEmpty()) {
           /* Iterator<MchReply> iterator = shopGrpcClient.getMerchants(mchIds.stream().distinct().collect(Collectors.toList()));
            while (iterator.hasNext()) {
                MchReply reply = iterator.next();
                mchMap.put(reply.getId(), reply.getName());
            }*/
        }
        Map<String, String> categoryMap;
        if (!categoryIds.isEmpty()) {
            List<Category> categories = categoryDao.selectByPrimaryKeys(categoryIds.stream().distinct().collect(Collectors.toList()));
            categoryMap = categories.stream().collect(Collectors.toMap(Category::getId, Category::getName));
        } else {
            categoryMap = new HashMap<>();
        }
        pageVo.setData(entities.stream().map(entity -> {
            BrandVo vo = new BrandVo();
            BeanUtils.copyProperties(entity, vo);
            vo.setMchName(mchMap.get(entity.getMchId()));
            vo.setCategoryName(categoryMap.get(entity.getCategoryId()));
            return vo;
        }).collect(Collectors.toList()));
        return pageVo;
    }

    public List<BrandVo> index(PageBo<BrandSearchBo> pageBo) {
        PageHelper.startPage(pageBo.getPage(), pageBo.getPageSize()).count(false);
        List<Brand> entities = brandMapper.findAll(pageBo.getParam());
        return entities.stream().map(this::convert).collect(Collectors.toList());
    }

    @Transactional(rollbackFor = Throwable.class)
    public void delete(String id) {
        brandMapper.delete(id);
    }

    private BrandVo convert(Brand entity) {
        BrandVo vo = new BrandVo();
        BeanUtils.copyProperties(entity, vo);
        return vo;
    }

    @Transactional(rollbackFor = Throwable.class)
    public BrandVo detail(String id, String userId) {
        Brand entity = brandMapper.findByPk(id);
        if (entity == null) {
            throw new CommonException(ExceptionCode.DATA_NOT_EXISTS);
        }
        return convert(entity);
    }

    public List<BrandVo> getByIds(List<String> ids) {
        List<Brand> entities = brandMapper.findByPks(ids);
        if (entities.isEmpty()) {
            return new ArrayList<>(0);
        }
        return entities.stream().map(entity -> convert(entity)).collect(Collectors.toList());
    }
}
